home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Monster Media 1996 #15
/
Monster Media Number 15 (Monster Media)(July 1996).ISO
/
prog_c
/
cuj0696.zip
/
DWYER.ZIP
/
QFLOAT
/
QLOG.C
< prev
next >
Wrap
C/C++ Source or Header
|
1996-03-31
|
1KB
|
87 lines
/* qlog.c */
/* natural logarithm */
#include <stdio.h>
#include "qhead.h"
extern QELT qone[], qtwo[], qlog2[], qsqrt2[];
int qlog( x, y )
QELT *x, *y;
{
QELT xx[NQ], z[NQ], a[NQ], b[NQ], t[NQ], qj[NQ];
long ex;
if( x[0] != 0 )
{
qclear(y);
printf( "qlog domain error\n" );
return 0;
}
if( x[1] == 0 )
{
qinfin( y );
y[0] = -1;
printf( "qlog singularity\n" );
return 0;
}
/* range reduction: log x = log( 2**ex * m ) = ex * log2 + log m */
qmov(x, xx );
ex = *(xx+1);
if( ex == EXPONE )
{ /* log 1 = 0 */
if( qcmp(x, qone) == 0 )
{
qclear(y);
return 0;
}
}
ex -= (EXPONE-1);
xx[1] = (EXPONE-1);
/* Adjust range to 1/sqrt(2), sqrt(2) */
qsqrt2[1] -= 1;
if( qcmp( xx, qsqrt2 ) < 0 )
{
ex -= 1;
xx[1] += 1;
}
qsqrt2[1] += 1;
qadd( qone, xx, b );
qsub( qone, xx, a );
if( a[1] == 0 )
{
qclear(y);
goto bdone;
}
qdiv( b, a, y ); /* store (x-1)/(x+1) in y */
qmul( y, y, z );
qmov( qone, a );
qmov( qone, b );
qmov( qone, qj );
do
{
qadd( qtwo, qj, qj ); /* 2 * i + 1 */
qmul( z, a, a );
qdiv( qj, a, t );
qadd( t, b, b );
}
while( ((int) b[1] - (int) t[1]) < NBITS );
qmul( b, y, y );
y[1] += 1;
bdone:
/* now add log of 2**ex */
if( ex != 0 )
{
ltoq( &ex, b );
qmul( qlog2, b, b );
qadd( b, y, y );
}
return 0;
}